package me.firstapp.config;

import java.io.IOException;
import java.sql.SQLException;
import java.util.Properties;

import org.hibernate.SessionFactory;
import org.springframework.beans.factory.config.PropertiesFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
import org.springframework.core.io.ClassPathResource;
import org.springframework.orm.hibernate5.HibernateTemplate;
import org.springframework.orm.hibernate5.HibernateTransactionManager;
import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
import org.springframework.scheduling.quartz.CronTriggerFactoryBean;
import org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.web.client.RestTemplate;

import com.alibaba.druid.pool.DruidDataSource;

import me.firstapp.bts.JobTask;

@Configuration
@ImportResource("classpath:transaction.xml")
@ComponentScan(basePackages = { "me.firstapp.module", "me.firstapp.repository", "me.firstapp.service",
		"me.firstapp.bts.service" })
public class RootConfig {

	@Bean
	public PropertiesFactoryBean configProperties() {
		PropertiesFactoryBean configProperties = new PropertiesFactoryBean();
		configProperties.setLocations(new ClassPathResource("jdbc.properties"),
				new ClassPathResource("config.properties"));
		return configProperties;
	}

	@Bean
	public RestTemplate restTemplate() {
		return new RestTemplate();
	}

	// ==============================数据源配置==================================
	@Bean
	public DruidDataSource dataSource(PropertiesFactoryBean configProperties) {
		DruidDataSource druidDataSource = new DruidDataSource();
		try {
			Properties properties = configProperties.getObject();
			// 基本属性 url、user、password
			druidDataSource.setUrl(properties.getProperty("database.jdbcUrl"));
			druidDataSource.setUsername(properties.getProperty("database.user"));
			druidDataSource.setPassword(properties.getProperty("database.password"));
			// 配置初始化大小、最小、最大
			druidDataSource.setInitialSize(Integer.valueOf(properties.getProperty("database.initialSize")));
			druidDataSource.setMinIdle(Integer.valueOf(properties.getProperty("database.minIdle")));
			druidDataSource.setMaxActive(Integer.valueOf(properties.getProperty("database.maxActive")));
			// 配置获取连接等待超时的时间
			druidDataSource.setMaxWait(Integer.valueOf(properties.getProperty("database.maxWait")));
			// 配置一个连接在池中最小生存的时间，单位是毫秒
			druidDataSource.setMinEvictableIdleTimeMillis(
					Integer.valueOf(properties.getProperty("database.minEvictableIdleTimeMillis")));
			druidDataSource.setValidationQuery(properties.getProperty("database.validationQuery"));
			druidDataSource.setTestWhileIdle(Boolean.valueOf(properties.getProperty("database.testWhileIdle")));
			druidDataSource.setTestOnBorrow(Boolean.valueOf(properties.getProperty("database.testOnBorrow")));
			druidDataSource.setTestOnReturn(Boolean.valueOf(properties.getProperty("database.testOnReturn")));

			// 打开PSCache，并且指定每个连接上PSCache的大小
			druidDataSource.setPoolPreparedStatements(
					Boolean.valueOf(properties.getProperty("database.poolPreparedStatements")));
			druidDataSource.setMaxPoolPreparedStatementPerConnectionSize(
					Integer.valueOf(properties.getProperty("database.maxPoolPreparedStatementPerConnectionSize")));

			// 配置监控统计拦截的filters
			druidDataSource.setFilters("stat");
		} catch (IOException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return druidDataSource;
	}

	// ============================hibernate配置=====================================
	@Bean
	public LocalSessionFactoryBean sessionFactory(DruidDataSource dataSource) {
		LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
		sessionFactory.setDataSource(dataSource);
		Properties properties = new Properties();
		properties.put("hibernate.dialect", "org.hibernate.dialect.MySQL5InnoDBDialect");
		properties.put("hibernate.show_sql", false);
		properties.put("hibernate.hbm2ddl.auto", "update");
		sessionFactory.setHibernateProperties(properties);
		sessionFactory.setPackagesToScan("me.firstapp.module", "me.firstapp.common");
		return sessionFactory;
	}

	@Bean
	public HibernateTemplate hibernateTemplate(LocalSessionFactoryBean sessionFactory) {
		HibernateTemplate hibernateTemplate = new HibernateTemplate();
		hibernateTemplate.setSessionFactory(sessionFactory.getObject());
		return hibernateTemplate;
	}

	// =================================事务配置==================================================
	@Bean
	public HibernateTransactionManager transactionManager(SessionFactory sessionFactory) {
		HibernateTransactionManager transactionManager = new HibernateTransactionManager();
		transactionManager.setSessionFactory(sessionFactory);
		return transactionManager;
	}

	@Bean
	public TransactionTemplate transactionTemplate(HibernateTransactionManager transactionManager) {
		TransactionTemplate transactionTemplate = new TransactionTemplate();
		transactionTemplate.setTransactionManager(transactionManager);
		return transactionTemplate;
	}

	// ==============================定时任务配置start========================================
	@Bean
	public SchedulerFactoryBean schedulerFactory(JobTask jobTask) {
		SchedulerFactoryBean scheduler = new SchedulerFactoryBean();
		scheduler.setAutoStartup(true);
		CronTriggerFactoryBean orderExpireTrigger = orderExpireTrigger(jobTask);
		CronTriggerFactoryBean orderSettleTrigger = orderSettleTrigger(jobTask);
		CronTriggerFactoryBean settleWeibiToJinbiTrigger = settleWeibiToJinbiTrigger(jobTask);
		CronTriggerFactoryBean fansCountsTaskTrigger = fansCountsTaskTrigger(jobTask);
		CronTriggerFactoryBean checkExpireTaskTrigger = checkExpireTaskTrigger(jobTask);
		CronTriggerFactoryBean offTransferTaskTrigger = offTransferTaskTrigger(jobTask);
		CronTriggerFactoryBean addTransferMemberTaskTrigger = addTransferMemberTaskTrigger(jobTask);
		scheduler.setTriggers(orderExpireTrigger.getObject(), orderSettleTrigger.getObject(),
				fansCountsTaskTrigger.getObject(), checkExpireTaskTrigger.getObject(),
				settleWeibiToJinbiTrigger.getObject(), offTransferTaskTrigger.getObject(),
				addTransferMemberTaskTrigger.getObject());
		return scheduler;
	}

	@Bean
	public JobTask jobTask() {
		return new JobTask();
	}

	// ==============================未支付订单过期处理
	// start========================================
	@Bean(name = "orderExpireJobDetail")
	public MethodInvokingJobDetailFactoryBean orderExpireJobDetail(JobTask jobTask) {
		MethodInvokingJobDetailFactoryBean jobDetail = new MethodInvokingJobDetailFactoryBean();
		jobDetail.setTargetObject(jobTask);
		jobDetail.setTargetMethod("doOrderExpireTask");
		jobDetail.setConcurrent(false);
		return jobDetail;
	}

	@Bean
	public CronTriggerFactoryBean orderExpireTrigger(JobTask jobTask) {
		CronTriggerFactoryBean trigger = new CronTriggerFactoryBean();
		MethodInvokingJobDetailFactoryBean orderExpireJobDetail = orderExpireJobDetail(jobTask);
		trigger.setJobDetail(orderExpireJobDetail.getObject());
		trigger.setCronExpression("0 0/10 * * * ? ");// 百度搜索 quartz cron表达式
		return trigger;
	}
	// ==============================未支付订单过期处理
	// end========================================

	// ==============================结算订单任务处理start========================================
	@Bean(name = "doOrderSettleJobDetail")
	public MethodInvokingJobDetailFactoryBean doOrderSettleJobDetail(JobTask jobTask) {
		MethodInvokingJobDetailFactoryBean jobDetail = new MethodInvokingJobDetailFactoryBean();
		jobDetail.setTargetObject(jobTask);
		jobDetail.setTargetMethod("doOrderSettleTask");
		jobDetail.setConcurrent(false);
		return jobDetail;
	}

	@Bean
	public CronTriggerFactoryBean orderSettleTrigger(JobTask jobTask) {
		CronTriggerFactoryBean trigger = new CronTriggerFactoryBean();
		MethodInvokingJobDetailFactoryBean orderSettleDetail = doOrderSettleJobDetail(jobTask);
		trigger.setJobDetail(orderSettleDetail.getObject());
		trigger.setCronExpression("0 0/1 * * * ? ");// 百度搜索 quartz cron表达式
		// 在线生成器
		return trigger;
	}
	// ==============================结算订单任务处理end========================================

	// //
	// ==============================积分结算贝币任务处理start========================================
	@Bean(name = "doSettleWeibiToJinbiJobDetail")
	public MethodInvokingJobDetailFactoryBean doSettleWeibiToJinbiJobDetail(JobTask jobTask) {
		MethodInvokingJobDetailFactoryBean jobDetail = new MethodInvokingJobDetailFactoryBean();
		jobDetail.setTargetObject(jobTask);
		jobDetail.setTargetMethod("doSettleWeibiToJinbiTask");
		jobDetail.setConcurrent(false);
		return jobDetail;
	}

	@Bean
	public CronTriggerFactoryBean settleWeibiToJinbiTrigger(JobTask jobTask) {
		CronTriggerFactoryBean trigger = new CronTriggerFactoryBean();
		MethodInvokingJobDetailFactoryBean settleWeibiToJinbiDetail = doSettleWeibiToJinbiJobDetail(jobTask);
		trigger.setJobDetail(settleWeibiToJinbiDetail.getObject());
		trigger.setCronExpression("0 5 0 1/1 * ? ");// 百度搜索 quartz cron表达式
		// 在线生成器
		return trigger;
	}
	// //
	// ==============================积分结算贝币任务处理end========================================

	// ==============================下架超时转让任务处理start========================================
	@Bean(name = "doOffTransferTaskDetail")
	public MethodInvokingJobDetailFactoryBean doOffTransferTaskDetail(JobTask jobTask) {
		MethodInvokingJobDetailFactoryBean jobDetail = new MethodInvokingJobDetailFactoryBean();
		jobDetail.setTargetObject(jobTask);
		jobDetail.setTargetMethod("doOffTransferTask");
		jobDetail.setConcurrent(false);
		return jobDetail;
	}

	@Bean
	public CronTriggerFactoryBean offTransferTaskTrigger(JobTask jobTask) {
		CronTriggerFactoryBean trigger = new CronTriggerFactoryBean();
		MethodInvokingJobDetailFactoryBean offTransferTaskDetail = doOffTransferTaskDetail(jobTask);
		trigger.setJobDetail(offTransferTaskDetail.getObject());
		trigger.setCronExpression("0 0 2 1/1 * ? ");// 百度搜索 quartz cron表达式
		// 在线生成器
		return trigger;
	}
	// ==============================下架超时转让任务处理end========================================

	// ==============================粉丝数量任务处理start========================================
	@Bean(name = "doFansCountsTaskDetail")
	public MethodInvokingJobDetailFactoryBean doFansCountsTaskDetail(JobTask jobTask) {
		MethodInvokingJobDetailFactoryBean jobDetail = new MethodInvokingJobDetailFactoryBean();
		jobDetail.setTargetObject(jobTask);
		jobDetail.setTargetMethod("doFansCountsTask");
		jobDetail.setConcurrent(false);
		return jobDetail;
	}

	@Bean
	public CronTriggerFactoryBean fansCountsTaskTrigger(JobTask jobTask) {
		CronTriggerFactoryBean trigger = new CronTriggerFactoryBean();
		MethodInvokingJobDetailFactoryBean fansCountsDetail = doFansCountsTaskDetail(jobTask);
		trigger.setJobDetail(fansCountsDetail.getObject());
		trigger.setCronExpression("0 0 4 1/1 * ? ");// 百度搜索 quartz cron表达式
		// 在线生成器
		return trigger;
	}
	// ==============================粉丝数量任务处理end========================================

	// ==============================新增转让用户任务处理start========================================
	@Bean(name = "doAddTransferMemberTaskDetail")
	public MethodInvokingJobDetailFactoryBean doAddTransferMemberTaskDetail(JobTask jobTask) {
		MethodInvokingJobDetailFactoryBean jobDetail = new MethodInvokingJobDetailFactoryBean();
		jobDetail.setTargetObject(jobTask);
		jobDetail.setTargetMethod("doAddTransferMemberTask");
		jobDetail.setConcurrent(false);
		return jobDetail;
	}

	@Bean
	public CronTriggerFactoryBean addTransferMemberTaskTrigger(JobTask jobTask) {
		CronTriggerFactoryBean trigger = new CronTriggerFactoryBean();
		MethodInvokingJobDetailFactoryBean addTransferMemberTaskDetail = doAddTransferMemberTaskDetail(jobTask);
		trigger.setJobDetail(addTransferMemberTaskDetail.getObject());
		trigger.setCronExpression("0 0 6 1/1 * ? ");// 百度搜索 quartz cron表达式
		// 在线生成器
		return trigger;
	}
	// ==============================新增转让用户任务处理end========================================

	// ==============================检查过期任务处理start========================================
	@Bean(name = "doCheckExpireTaskDetail")
	public MethodInvokingJobDetailFactoryBean doCheckExpireTaskDetail(JobTask jobTask) {
		MethodInvokingJobDetailFactoryBean jobDetail = new MethodInvokingJobDetailFactoryBean();
		jobDetail.setTargetObject(jobTask);
		jobDetail.setTargetMethod("doCheckExpireTask");
		jobDetail.setConcurrent(false);
		return jobDetail;
	}

	@Bean
	public CronTriggerFactoryBean checkExpireTaskTrigger(JobTask jobTask) {
		CronTriggerFactoryBean trigger = new CronTriggerFactoryBean();
		MethodInvokingJobDetailFactoryBean checkExpireDetail = doCheckExpireTaskDetail(jobTask);
		trigger.setJobDetail(checkExpireDetail.getObject());
		trigger.setCronExpression("0 0 9 1/1 * ? ");// 百度搜索 quartz cron表达式
		// 在线生成器
		return trigger;
	}
	// ==============================检查过期任务处理end========================================
}
